
 import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

import { createProduct , getStoryByunitNum , TweenMaxTo , getOffsetByUnitNum  } from "../libs/common.js";
import { config } from './config.js';
import $ from 'jquery';


var preChooseProductIndex = 0;
var _statckObj = {};

var scene = new THREE.Scene();
scene.background = new THREE.Color().setHSL( 0.6, 0, 1 );

var productGroup = new THREE.Group();
scene.add(productGroup);
/**
* 光源设置
*/
// 平行光1
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(40, 20, 30);
scene.add(directionalLight);
// 平行光2
var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight2.position.set(-40, -20, -30);
scene.add(directionalLight2);

//环境光
var ambient = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambient);


var width  = 400; //窗口文档显示区的宽度
var height = 400; //窗口文档显示区的高度
console.log(width,height);

/** 相机设置*/
var k = width / height; //Three.js输出的Cnavas画布宽高比
var s = 200; //控制相机渲染空间左右上下渲染范围，s越大，相机渲染范围越大
// -s * k, s * k, s, -s, 1, 1000定义了一个长方体渲染空间，渲染空间外的模型不会被渲染
// var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
var camera = new THREE.PerspectiveCamera( 45, k , 0.1, 100 );
camera.position.set(config.productSceneCameraIntitalPos.x,config.productSceneCameraIntitalPos.y,config.productSceneCameraIntitalPos.z); //相机在Three.js坐标系中的位置
camera.lookAt(0, 0, 0); //相机指向Three.js坐标系原点



// 辅助线
var axesHelper = new THREE.AxesHelper(100);
// scene.add(axesHelper);

/**
 * 创建渲染器对象
 */
var renderer = new THREE.WebGLRenderer({
    antialias: true, //开启锯齿
});
renderer.setPixelRatio(window.devicePixelRatio);//设置设备像素比率,防止Canvas画布输出模糊。
renderer.setSize(width, height); //设置渲染区域尺寸
// var dom = document.getElementById('productScene');
// dom.appendChild(renderer.domElement); //body元素中插入canvas对象

var controls = new OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI / 2 - 0.01;
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
controls.dampingFactor = 0.25;
controls.enableZoom = true;
// controls.autoRotate = true;
controls.minDistance  = 2;
controls.maxDistance  = 50;
controls.enablePan = true;


// 产品列表
$(".productList").on("click",".product",function(){
    if(config.productSceneCameraIsRun) return;
    var index = $(this).attr("data-index");
    if(index != preChooseProductIndex)
    {


        showProduct(_statckObj.stackInfos,index);
        preChooseProductIndex = index;


        // 根据编号 查找产品数据
        var productData =_statckObj.stackInfos[preChooseProductIndex];
        if(productData)
        {
            renderNews(productData,"productNews");//渲染产品信息
        }
    }

    $(this).eq(0).addClass("active").siblings().removeClass("active");
    
})



// 尺寸适配
function onReSize(w,h)
{
    camera.aspect = w/h;
    camera.updateProjectionMatrix();
    renderer.setSize(w,h);
}

// 帧循环
function productSceneLoop()
{
    controls.update();
    renderer.render( scene , camera );
}


function productSceneLoad(renderContent,statckObj,calback)
{
    var width  = renderContent.clientWidth;
    var height = renderContent.clientHeight;

    renderContent.appendChild(renderer.domElement);
    productGroup.traverse((child) => {
        if (child.material) {
            child.material.dispose();
        }
        if (child.geometry) {
            child.geometry.dispose();
        }
        child = null;
    });
    productGroup.clear();
    _statckObj = statckObj;//本地储存

    var stackInfos = _statckObj.stackInfos;
    let startNum = 1;

    stackInfos.forEach(stackInfo => {
        stackInfo.startNum = startNum;
        var endNum = startNum + stackInfo.goodsCount;
        stackInfo.endNum = endNum;

        var goodsLevel = stackInfo.goodsLevel * 1;
        var statusType =  config.stack.statusTypes[goodsLevel]; 

        for (let index = startNum; index < endNum; index++) {

            if(index > config.unit.maxNum ) return;
            var StoryData = getStoryByunitNum(index);
            var product_unit = config.unit[StoryData.pos_type][StoryData.StoryIndex-1];
        
            var Product   =  createProduct(config.unit.sX,config.unit.sH,config.unit.sY,product_unit.rx,product_unit.ry,product_unit.rz);
            Product.name  = stackInfo.companyName;
            Product.goodIndex = index;
            Product.material.opacity = 0.1;

            var pos = new THREE.Vector3(
                product_unit.x * config.unit.sX + config.unit.sX / 2 -  config.stack.sX_half,
                product_unit.y + config.unit.sH / 2 - 15 / 2 + (StoryData.Story - 1) * config.unit.sH,
                - product_unit.z * config.unit.sX - config.unit.sY / 2 + config.stack.sY_half - product_unit.z * config.unit.z_offset);

            if(product_unit.ry != 0) //不等于0 就是旋转90度了，需要跳动x坐标
            {
                Product.rotation.y = Math.PI / 2;
                switch(StoryData.pos_type)
                {
                    case "pos_type1":
                        pos.x -= (config.unit.sX -  config.unit.sY) / 1.5;
                        pos.z -= (config.unit.sY -  config.unit.sX) / 6;
                        break;
                    case "pos_type2":
                        pos.x += (config.unit.sY -  config.unit.sX) / 2;
                        pos.z =  - product_unit.z * (config.unit.sY -  config.unit.sX) - config.unit.sX / 2 + config.stack.sY_half - product_unit.z * config.unit.z_offset;
                        break;
                    case "pos_type3":
                        pos.z =  - product_unit.z * (config.unit.sY -  config.unit.sX) - config.unit.sX / 2 + config.stack.sY_half - product_unit.z * config.unit.z_offset;
                        break;
                }
            
            }else{
                Product.rotation.y = 0;
            }

            var color = new THREE.Color(statusType.color) ;
            Product.position.copy(pos);
            Product.material.color.set(color);
            productGroup.add(Product);
        }
        startNum = endNum;
    })

    onReSize(width,height);

    camera.position.set(config.productSceneCameraIntitalPos.x,config.productSceneCameraIntitalPos.y,config.productSceneCameraIntitalPos.z); //相机在Three.js坐标系中的位置
    // 默认第一个产品
    preChooseProductIndex = 0;
    showProduct(stackInfos,preChooseProductIndex);
    

    calback && calback(statckObj,stackInfos)
}



function showProduct(stackInfos,index)
{
    var startNum = stackInfos[index].startNum;
    var endNum   = stackInfos[index].endNum;


    productGroup.children.forEach((child,index) => {
        if(index >= startNum-1 && index < endNum - 1)
        {
            child.material.opacity = 1;
        }else{
            child.material.opacity = 0.2;
        }
    })
   


    var p_index = Math.ceil((endNum - startNum) / 2 + startNum);

    var target = productGroup.children[p_index - 1];

    cameraToProduct(target);
}



// 摄像机动画
// 参数 mesh 对象
function cameraToProduct(product)
{
    
    if(config.productSceneCameraIsRun) return;
    config.productSceneCameraIsRun = true;

    var data1 = {
        t_x : controls.target.x,
        t_y : controls.target.y,
        t_z : controls.target.z,
        c_x : camera.position.x,
        c_y : camera.position.y,
        c_z : camera.position.z,
    }

    var targetPos = product.position.clone();
    var offset = getOffsetByUnitNum(product.goodIndex);
    // console.log(offset);
    var cameraPos = {x: targetPos.x  + offset.x, y: targetPos.y + offset.y ,z: targetPos.z + offset.z}
    var data2 = {
        t_x : targetPos.x,
        t_y : targetPos.y,
        t_z : targetPos.z,
        c_x : cameraPos.x,
        c_y : cameraPos.y,
        c_z : cameraPos.z,
    }

    function update()
    {
        camera.position.set(data1.c_x,data1.c_y,data1.c_z);
        controls.target.set(data1.t_x,data1.t_y,data1.t_z);
    }

    function calback()
    {
        config.productSceneCameraIsRun = false;
        // console.log(config.cameraTargetStack );
    }

    TweenMaxTo(data1,data2,0.7,update,calback);
}




export{ productSceneLoop , productSceneLoad , onReSize , cameraToProduct , showProduct};